/*************************************************************************
    > File Name: pwd.c
    > Author: Xing.Dai
    > Mail: Xing.Dai@aliyun.com 
    > Created Time: 2017-05-25 19:19
 ************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h> 
#include <sys/types.h> 
#include <sys/stat.h> 
#include <dirent.h>

#define BUF_SIZE	100

/**
 * @Synopsis  get file i-node.
 *
 * @Param filename
 *
 * @Returns   
 */
ino_t get_inode(char *filename)
{
	struct stat info;

	if(stat(filename, &info) == -1){
		fprintf(stderr, "Can not stat");
		perror(filename);
	}

	return info.st_ino;
}


/**
 * @Synopsis  Looks through current directory for a file with this inode
 *			number and copies its name into *name
 *
 * @Param inode 
 * @Param name	output file name.
 * @Param buflen
 */
void inode2name(ino_t inode, char *name, int buflen)
{
	DIR *dir_p;
	struct dirent *dirent_p;
	
	dir_p = opendir(".");

	if(dir_p == NULL){
		perror(".");
		exit(1);
	}
	
	while((dirent_p = readdir(dir_p)) != NULL){
		if(dirent_p->d_ino == inode){
			strncpy(name, dirent_p->d_name, buflen);
			name[buflen - 1] = '\0';	/* Just in case of overflow. */
			closedir(dir_p);
			return;
		}
	}
	fprintf(stderr, "error looking for i-node %d\n", (int)inode);
	exit(1);
}

/**
 * @Synopsis  prints path leading down to an object with this inode.
 *			  kindof recursive. 
 *
 * @Param this_inode
 */
void print_file_path(ino_t this_inode)
{
	ino_t my_inode;
	char name[BUF_SIZE];

	if(get_inode("..") != this_inode){
		/* if this directory is root, "." & ".." are the same inode. */
		chdir("..");	/* up one directory. */
		inode2name(this_inode, name, BUF_SIZE);	/* buffer file path name*/
		my_inode = get_inode(".");
		print_file_path(my_inode);	/* Recursively. */
		printf("/%s", name);
	}
}

/**
 * @Synopsis  
 *
 * @Returns   
 */
int main()
{
	print_file_path(get_inode("."));
	putchar('\n');	/* add new line. */
	return 0;
}
